#include "myTimer.h"

#include <stdio.h>
#include <string.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gptimer.h"
#include "esp_attr.h"
#include "esp_log.h"

#include "cJSON.h"

#include "myTCP.h"
static const char *TAG = "myTimer";
static gptimer_handle_t gptimer = NULL;
static uint8_t game_flag = 0; // 游戏是否进行标志位，置一表示正在进行
#define GAME_TIME 125
static bool IRAM_ATTR example_timer_on_alarm_cb_v1(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
{
  static uint16_t gameTime_counter = 0;
  gameTime_counter++;
  xQueueSendFromISR((QueueHandle_t)user_data, &gameTime_counter, NULL);
  if (game_flag == 0 || gameTime_counter == GAME_TIME){
    gameTime_counter = 0;
    gptimer_stop(timer);
  }
  return true;
}

void timer_news_handle_task(void *arg)
{
  QueueHandle_t timer_news_queue = (QueueHandle_t)arg;
  uint16_t gameTime_counter = 0;
  // json
  cJSON *json = NULL;

  while (1)
  {
    xQueueReceive(timer_news_queue, &gameTime_counter, portMAX_DELAY);
    if (gameTime_counter == GAME_TIME)
    {
      game_flag = 0;
      json = cJSON_CreateObject();
      ESP_LOGI(pcTaskGetName(NULL), "Game stop!");

      cJSON_AddStringToObject(json, "messageType", "2");
      static tcp_msg_t tcp_msg;
      tcp_msg.buf = (uint8_t *)cJSON_Print(json);
      tcp_msg.len = strlen((char *)tcp_msg.buf);
      tcp_broadcast(&tcp_msg);
      cJSON_Delete(json);
    }
    else
      ESP_LOGI(pcTaskGetName(NULL), "gameTime_counter = %d.", gameTime_counter);
  }
}

void myTimer_init(void)
{
  /* Create timer news queue*/
  QueueHandle_t timer_news_queue = xQueueCreate(16, sizeof(uint16_t));

  gptimer_config_t timer_config = {
      .clk_src = GPTIMER_CLK_SRC_DEFAULT,
      .direction = GPTIMER_COUNT_UP,
      .resolution_hz = 1000000, // 1MHz, 1 tick=1us
  };
  ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer));

  gptimer_event_callbacks_t cbs = {
      .on_alarm = example_timer_on_alarm_cb_v1,
  };
  ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, timer_news_queue));

  ESP_ERROR_CHECK(gptimer_enable(gptimer));

  gptimer_alarm_config_t alarm_config1 = {
      .reload_count = 0,
      .alarm_count = 1000000, // period = 1s
      .flags.auto_reload_on_alarm = 1};
  ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config1));

  /* Create Timer news handle task */
  xTaskCreate(timer_news_handle_task, "timer_news_handle_task", 1024 * 2, timer_news_queue, 12, NULL);
}

void game_start_counting(void)
{
  game_flag = 1;
  cJSON *json = cJSON_CreateObject();
  ESP_LOGI(pcTaskGetName(NULL), "Game start!");

  cJSON_AddStringToObject(json, "messageType", "1");
  static tcp_msg_t tcp_msg;
  tcp_msg.buf = (uint8_t *)cJSON_Print(json);
  tcp_msg.len = strlen((char *)tcp_msg.buf);
  tcp_broadcast(&tcp_msg);
  cJSON_Delete(json);

  ESP_ERROR_CHECK(gptimer_start(gptimer));
}

void game_stop_out(void)
{
  if(game_flag){
    cJSON *json = cJSON_CreateObject();
    ESP_LOGI(pcTaskGetName(NULL), "Game stop!");
    cJSON_AddStringToObject(json, "messageType", "3");
    tcp_msg_t tcp_msg;
    tcp_msg.buf = (uint8_t *)cJSON_Print(json);
    tcp_msg.len = strlen((char *)tcp_msg.buf);
    tcp_broadcast(&tcp_msg);
    cJSON_Delete(json);
    game_flag = 0;
  }
}

void game_stop_die(void)
{
  if(game_flag){
    cJSON *json = cJSON_CreateObject();
    ESP_LOGI(pcTaskGetName(NULL), "Game stop!");
    cJSON_AddStringToObject(json, "messageType", "6");
    tcp_msg_t tcp_msg;
    tcp_msg.buf = (uint8_t *)cJSON_Print(json);
    tcp_msg.len = strlen((char *)tcp_msg.buf);
    tcp_broadcast(&tcp_msg);
    cJSON_Delete(json);
    game_flag = 0;
  }
}
